package main

import (
	_ "github.com/go-sql-driver/mysql"
	"xorm.io/xorm"
)

// 负载策略 ：https://xorm.io/zh/docs/chapter-01/3.policy/
// 通过 xorm.NewEngineGroup 创建 EngineGroup 时，第三个参数为 policies，
// 我们可以通过该参数来指定 Slave 访问的负载策略。如创建EngineGroup 时未指定，则默认使用轮询的负载策略。
//
// xorm 中内置五种负载策略，
// 分别为随机访问负载策略，
// 权重随机访问负载策略，
// 轮询访问负载策略，
// 权重轮询访问负载策略和最小连接数访问负载策略。
// 开发者也可以通过实现 GroupPolicy 接口，来实现自定义负载策略。
func main() {
	enginGroup01()
	//enginGroup02()
}

func enginGroup01() {
	var eg *xorm.EngineGroup
	conns := []string{
		"root:root123@tcp(127.0.0.1:3306)/xorm1?charset=utf8mb4&parseTime=True&loc=Local", // 第一个默认是master
		"root:root123@tcp(127.0.0.1:3306)/xorm2?charset=utf8mb4&parseTime=True&loc=Local", // 第二个开始都是slave
		"root:root123@tcp(127.0.0.1:3306)/xorm3?charset=utf8mb4&parseTime=True&loc=Local",
	}

	var err error
	eg, err = xorm.NewEngineGroup("mysql", conns)

	//---------------访问策略---------------默认RoundRobinPolicy
	//1.随机访问负载策略
	eg, err = xorm.NewEngineGroup("mysql", conns, xorm.RandomPolicy())
	//2.权重随机访问负载策略:此时设置的xorm2数据库和xorm3数据库的随机访问权重为2和3
	eg, err = xorm.NewEngineGroup("mysql", conns, xorm.WeightRandomPolicy([]int{2, 3}))
	//3.轮询访问负载策略:轮询访问负载策略
	eg, err = xorm.NewEngineGroup("mysql", conns, xorm.RoundRobinPolicy())
	//4.权重轮询访问负载策略:此时设置的xorm2数据库和xorm3数据库的轮询访问权重为2和3
	eg, err = xorm.NewEngineGroup("mysql", conns, xorm.WeightRoundRobinPolicy([]int{2, 3}))
	//5.最小连接数访问负载策略
	eg, err = xorm.NewEngineGroup("postgres", conns, xorm.LeastConnPolicy())
	//自定义负载策略:实现 GroupPolicy 接口来实现自定义负载策略
	//type GroupPolicy interface {
	//	Slave(*EngineGroup) *Engine
	//}
	if err != nil {
		panic(err)
	}
	defer eg.Close()
	err = eg.Ping()
	if err != nil {
		panic(err)
	}

}
func enginGroup02() {
	var eg *xorm.EngineGroup

	var err error
	master, err := xorm.NewEngine("mysql", "root:root123@tcp(127.0.0.1:3306)/xorm1?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		return
	}

	slave1, err := xorm.NewEngine("mysql", "root:root123@tcp(127.0.0.1:3306)/xorm2?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		return
	}

	slave2, err := xorm.NewEngine("mysql", "root:root123@tcp(127.0.0.1:3306)/xorm3?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		return
	}

	slaves := []*xorm.Engine{slave1, slave2}
	eg, err = xorm.NewEngineGroup(master, slaves)
	err = eg.Ping()
	if err != nil {
		panic(err)
	}
	defer eg.Close()
}
